//
//  GNRBLEFriendsManager.m
//  Faceto
//
//  Created by LvYuan on 2017/4/26.
//  Copyright © 2017年 LvYuan. All rights reserved.
//

#import "GNRBLEFriendsManager.h"
#import "GNRHelper.h"
#import "UIAlertView+MKBlockAdditions.h"

#define kConnectDelayTime 30

@interface GNRBLEFriendsManager()
{
    BOOL readProfile;//已读取过
    BOOL writeProfile;//已写入过
}
@property (nonatomic, strong)NSTimer * timer;//链接失效30s
@property (nonatomic, strong)GNRBLEFriendModel * willConnectFriendModel;//准备连接好友模型
@end

@implementation GNRBLEFriendsManager

+ (instancetype)manager{
    static GNRBLEFriendsManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        _timer = [NSTimer timerWithTimeInterval:kConnectDelayTime repeats:NO block:^(NSTimer * _Nonnull timer) {
            NSLog(@"asdasdasd");
        }];
        _connectFriends = [NSMutableArray array];
    }
    return self;
}

//开始扫描
- (void)startScanWithScanCompletion:(GNRBLEScanSucceeBlock)block error:(GNRBLEScanErrorBlock)errorBlock {
    
    [[GNRBLECentralManager manager] starScanPeripheralForServices:@[UUID_Service_Read_ProfileInfo,UUID_Service_Notify_HeartRate] succee:^(NSMutableArray<GNRPeripheral *> *peripherals) {
        if (block) {
            block(peripherals);
        }
    } error:^(NSError *error) {
        if (errorBlock) {
            errorBlock(error);
        }
    }];
}



//停止扫描
- (void)stopScan{
    [[GNRBLECentralManager manager] stopScan];
}

//是否已经连接
- (BOOL)isConnectForPer:(GNRPeripheral *)per{
    for (GNRBLEFriendModel * fModel in self.connectFriends) {
        if ([fModel.name isEqualToString:per.name]) {
            return YES;
        }
    }
    return per.peripheral.state == CBPeripheralStateConnected;
}

/**
 连接设备 并扫描该的服务及特征
 */
- (void)connectForPeripheral:(GNRPeripheral *)connectPeripheral
             readProfileInfo:(GNRBLEReadProfileInfoBlock)readBlock
                   subscribe:(GNRBLESubscribeBlock)subscribeBlock{
    
    if (![GNRDataStore store].isLogin||
        ![GNRDataStore store].UserName||
        ![GNRDataStore store].profileParam.nickname) {
        return;
    }
    if ([self isConnectForPer:connectPeripheral]) {
        [SVProgressHUD showInfoWithStatus:@"你已连接该设备"];
        return;
    }
    _subBlock = nil;
    _subBlock = [subscribeBlock copy];
    _readBlock = nil;
    _readBlock = [readBlock copy];
    
    GNRBLECentralManager * manager = [GNRBLECentralManager manager];
    manager.name = [GNRDataStore store].profileParam.nickname;
    manager.identification = [GNRDataStore store].UserName;
    manager.profileInfo = @{
                            @"identification":[GNRDataStore store].UserName?:@"",
                            @"nickname":[GNRDataStore store].profileParam.nickname?:@"",
                            @"head":[GNRDataStore store].profileParam.head?:@""
                            };
    [[GNRBLECentralManager manager] connectForPeripheral:connectPeripheral connectCompletion:^(GNRPeripheral *peripheral, NSError *error) {
        if (_connectBlock) {
            _connectBlock(peripheral,error);
        }
    } disconnectCompletion:^(GNRPeripheral *peripheral, NSError *error) {
        NSLog(@"disconnect");
        if ([self removePer:peripheral]) {
            if (_friendsChangeBlock) {
                _friendsChangeBlock(self.connectFriends,error);
            }
        }
        [manager removePer:peripheral];

        if (_disConnetBlock) {
            _disConnetBlock(peripheral,error);
        }
    }];
    
    //扫描到特征的回调
    manager.characteristicCompletion = ^(GNRPeripheral * peripheral,GNRCharacteristic * chara,NSError * error){
        if (error) {
            
        }else{
            if ([chara.identifier isEqualToString:UUID_Characteristic_UserInfo]) {
                //先读取用户信息
                [self readProfileForPeripheral:connectPeripheral];
                readProfile = YES;
            }else if ([chara.identifier isEqualToString:UUID_Characteristic_GetUserInfo]) {
                [self writeProfileForPeripheral:connectPeripheral];
                writeProfile = YES;
            }
        }
    };
}

- (BOOL)removePer:(GNRPeripheral *)peripheral{
    for (GNRBLEFriendModel * fModel in self.connectFriends) {
        if ([peripheral.identifier isEqualToString:fModel.per.identifier]) {
            [self.connectFriends removeObject:fModel];
            
            return YES;
        }
    }
    return NO;
    
}

//取消订阅
- (void)unSubscribe:(GNRPeripheral *)connectPeripheral
          subscribe:(GNRBLESubscribeBlock)subscribeBlock{
    [[GNRBLECentralManager manager]disNotifyPeripheral:connectPeripheral completion:^(GNRPeripheral *peripheral, NSError *error) {
        if (subscribeBlock) {
            subscribeBlock(peripheral,error);
        }
    }];
    [[[GNRBLECentralManager manager] centralManager] cancelPeripheralConnection:connectPeripheral.peripheral];
}

- (GNRBLEFriendModel *)getFriendForPer:(GNRPeripheral *)per{
    for (GNRBLEFriendModel * fModel in self.connectFriends) {
        if ([fModel.name isEqualToString:per.name]) {
            return fModel;
        }
    }
    GNRBLEFriendModel * fModel = [GNRBLEFriendModel new];
    fModel.per = per;
    return fModel;
}

//读取特征值
- (void)readProfileForPeripheral:(GNRPeripheral *)per{
    [[GNRBLECentralManager manager] readValueForPeripheral:per completion:^(id result, NSError *error) {
        if (error) {
            NSLog(@"特征值读取错误 %@",error);
        }else{
            //读取到用户信息
            NSDictionary * profileDict = [GNRHelper objWithJsonString:result];
            [per.profileInfo setValuesForKeysWithDictionary:profileDict];
            [self subscribeForPeripheral:per];
        }
        if (_readBlock) {
            _readBlock(per,result,error);
        }
    }];
}

- (void)writeProfileForPeripheral:(GNRPeripheral *)per{
    [[GNRBLECentralManager manager] writeValueForPeripheral:per completion:^(GNRPeripheral *peripheral, NSError *error) {
        if (error) {
            
        }else{
            NSLog(@"成功写入！");
            [self subscribeForPeripheral:per];
        }
    }];
}

- (BOOL)isExsitForFriendName:(NSString *)name{
    for (GNRBLEFriendModel * fModel in self.connectFriends) {
        if ([name isEqualToString:fModel.name]) {
            return YES;
        }
    }
    return NO;
}

//订阅
- (void)subscribeForPeripheral:(GNRPeripheral *)per{
    if (readProfile&&writeProfile) {
        //已连接
        if ([self isExsitForFriendName:per.name]==NO) {//新连接的一位好友
            GNRBLEFriendModel * fModel = [GNRBLEFriendModel new];
            fModel.per = per;
            fModel.connected = YES;
            [self.connectFriends addObject:fModel];
            if (_friendsChangeBlock) {
                _friendsChangeBlock(self.connectFriends,nil);
            }
        }
        
        [[GNRBLECentralManager manager] notifyPeripheral:per completion:^(GNRPeripheral *peripheral, NSError *error) {
            if (_subBlock) {
                _subBlock(peripheral,error);
            }
        }];
        readProfile = NO;
        writeProfile = NO;
    }
}

//开启外设广播
- (void)openPeripheralService{
    if (![GNRDataStore store].isLogin||
        ![GNRDataStore store].UserName||
        ![GNRDataStore store].profileParam.nickname) {
        return;
    }
    GNRBLEPeripheralManager * manager = [GNRBLEPeripheralManager manager];
    manager.name = [GNRDataStore store].profileParam.nickname;
    manager.identification = [GNRDataStore store].UserName;
    manager.profileInfo = @{
                            @"identification":[GNRDataStore store].UserName?:@"",
                            @"nickname":[GNRDataStore store].profileParam.nickname?:@"",
                            @"head":[GNRDataStore store].profileParam.head?:@""
                            };
    if (manager.peripheralManger) {
        [manager startAdvertising];
    }else{
        [manager openPeripheralSuccee:^(CBPeripheralManager *perManager) {
            NSLog(@"服务已经开启，开始广播");
            [manager startAdvertising];
        } error:^(NSError *error) {
            NSLog(@"服务开启失败！");
        }];
    }
    
    //被订阅的通知
    [manager  revProfileInfoBlock:^(GNRCentral *central, id result) {
        if (central && result) {
            
            [UIAlertView alertViewWithTitle:@"连接请求" message:[NSString stringWithFormat:@"%@%@",central.name,@"想和你连接，是否接受？"] cancelButtonTitle:@"残忍拒绝" otherButtonTitles:@[@"连接"] onDismiss:^(int buttonIndex) {
                if (buttonIndex==0) {
                    //发送通知数据
                    [manager startSendForCentral:central];
                    GNRBLEFriendModel * fModel = [GNRBLEFriendModel new];
                    fModel.cen = central;
                    fModel.connected = YES;
                    [self.connectFriends addObject:fModel];
                    if (_friendsChangeBlock) {
                        _friendsChangeBlock(self.connectFriends,nil);
                    }
                }
            } onCancel:^{
                [manager refuseSubscribeForCentral:central];
            }];
        }
        
    } didSubscribeBlock:^(GNRCentral *central, CBCharacteristic *chara) {
        //开始被订阅
        
    }];
    
    //被取消订阅的通知
    [manager didUnsubscribeBlock:^(GNRCentral *central, CBCharacteristic *chara) {
        NSLog(@"%@ 取消了订阅",central.identifier);
        if ([self removeCen:central]) {
            if (_friendsChangeBlock) {
                _friendsChangeBlock(self.connectFriends,nil);
            }
        }
        [[GNRBLEPeripheralManager manager]removeCen:central];
        [manager stopSendNotify:central];
    }];
}

- (BOOL)removeCen:(GNRCentral *)cen{
    for (GNRBLEFriendModel * fmodel in self.connectFriends) {
        if ([fmodel.name isEqualToString:cen.name]) {
            [self.connectFriends removeObject:fmodel];
            return YES;
        }
    }
    return NO;
}

//关闭外设广播
- (void)closePeripheralService{
    GNRBLEPeripheralManager * manager = [GNRBLEPeripheralManager manager];
    [manager stopAdvertising];
}

@end
